/*------------------------------------------------------------------------------
* GeoVISTA Center, Penn State Geography Deptartment*
* Copyright (c), 2002, GeoVISTA Center
* All Rights Researved.
*
* Original Authors: Frank Hardisty, Bonan Li
* $Author: bonan_li $
*
* $Date: 2004/03/03 19:03:11 $
*
* $Id: LayerPointExtension.java,v 1.3 2004/03/03 19:03:11 bonan_li Exp $
*
* To Do:
*
 ------------------------------------------------------------------------------*/

package edu.psu.geovista.app.map;

import edu.psu.geovista.symbollibrary.SymbolInterface;

import java.awt.*;
import java.awt.geom.Ellipse2D;
import java.awt.geom.GeneralPath;
import java.awt.geom.PathIterator;
import java.awt.geom.Point2D;

/**
 * put your documentation comment here
 */
public class LayerPointExtension
    extends LayerShapeExtension implements LayerInterface{

  private Point2D[] originalPoints;

  private SymbolInterface[] symbols = null;

  public void setSymbols(SymbolInterface[] symbols) {
    this.symbols = symbols;
  }

  /*
   * selectionX1 is expected to be less than selectionX2, same with Y1 and y2
   */
  public void findSelection(int selectionX1, int selectionX2, int selectionY1,
                            int selectionY2) {
  }

  /*
   * selectionX1 is expected to be less than selectionX2, same with Y1 and y2
   */
  public void findSelectionShift(int selectionX1, int selectionX2,
                                 int selectionY1,
                                 int selectionY2) {
  }

  public int findIndication(int x, int y) {
    return Integer.MIN_VALUE;
  }

  /**
   * sets the points that the layer will use to draw from
   * these are assumed to be in user space
   * @param originalPoints
   */
  public void setOriginalPoints(Point2D[] originalPoints) {
    this.originalPoints = originalPoints;
  }

  /**
   * retrieves the points
   * @param originalPoints
   */
  public Point2D[] getOriginalPoints() {
    return this.originalPoints;
  }

  public Point2D[] shapesToPoints(Shape[] shapes) {
    Point2D[] points = new Point2D.Double[shapes.length];
    for (int i = 0; i < shapes.length; i++) {
      Point2D pnt = new Point2D.Double();
      Shape shp = shapes[i];
      PathIterator path = shp.getPathIterator(null);
      double[] seg = new double[6];
      int segType = path.currentSegment(seg);
      if (segType != path.SEG_MOVETO) {
        throw new IllegalArgumentException(
            "LayerPointExtension.shapesToPoints expects only PathIterator.SEG_MOVETO segments");
      }
      pnt.setLocation(seg[0], seg[1]);
      points[i] = pnt;
    }

    return points;
  }

  public Shape[] pointsToShapes(Point2D[] points) {
    Shape[] shapes = new Shape[points.length];
    for (int i = 0; i < shapes.length; i++) {
      GeneralPath shp = new GeneralPath();
      Point2D pnt = points[i];
      shp.moveTo( (float) pnt.getX(), (float) pnt.getY());
      shapes[i] = shp;
    }

    return shapes;
  }

  public Shape[] findShapesForPoints(Point2D[] points) {
    Shape[] shapes = new Shape[points.length];
    float shapeSize = 4f;
    float half = shapeSize / 2f;
    for (int i = 0; i < shapes.length; i++) {
      Point2D pt = points[i];

      Ellipse2D eli = new Ellipse2D.Float( (float) pt.getX() - half,
                                          (float) pt.getY() - half, shapeSize,
                                          shapeSize);
      GeneralPath path = new GeneralPath(eli);
      shapes[i] = path;
    }

    return shapes;
  }

  public void render(Graphics2D g2) {

    if (this.objectColors == null) {
      System.out.println("LayerShape, render called on null objectColors");
      return;
    }
    if (g2 == null) {
      throw new IllegalArgumentException(this.toString() +
          " Null graphics passed in to render(Graphics2D).");
    }
    if (this.isAuxiliary) {
       System.out.println("rendering auxiliary layer....point. ");
      super.renderAux(g2);
      return;
    }

    for (int path = 0; path < spatialData.length; path++) {
      this.renderObservationNoIndication(path, g2);
    }
  } //end method

  public void renderObservation(int obs, Graphics2D g2) {
    if (obs < 0) {
      return;
    }
    if (this.objectColors.length <= obs) {
      return;
    }

    Shape shp = spatialData[obs];
    if (fisheyes != null) {
      shp = fisheyes.transform(shp);
    }

    g2.setStroke(this.defaultStroke);
    Color color = this.objectColors[obs];
    g2.setColor(color);
    g2.fill(shp);

    if (this.defaultStrokeWidth >= 0.1f) {
      g2.setColor(this.colorLine);
      g2.draw(shp);
    }

    if (this.symbols != null) {
      shp.getBounds2D().getCenterX();
      shp.getBounds2D().getCenterY();
      this.renderSymbol(this.symbols[obs], shp.getBounds2D().getCenterX(),
                        shp.getBounds2D().getCenterY(), g2);
    }
  }

  public void renderObservationNoIndication(int obs, Graphics2D g2)
  {
    if (obs < 0) {
      return;
    }
    if (this.objectColors.length <= obs) {
      return;
    }

    Shape shp = spatialData[obs];
    if (fisheyes != null) {
      shp = fisheyes.transform(shp);
    }

    if (conditionArray[obs] > -1) {
      g2.setStroke(this.defaultStroke);
      if(!this.selOriginalColorMode || this.selectedObservationsFullIndex[obs] == this.STATUS_SELECTED ||!this.selectionExists){
        Color color = this.objectColors[obs];
        g2.setColor(color);
        g2.fill(shp);
      }

      if (this.defaultStrokeWidth >= 0.1f) {
        g2.setColor(this.colorLine);
        g2.draw(shp);
      }

      if (this.selOriginalColorMode) {
        if (this.selectedObservationsFullIndex[obs] == this.STATUS_NOT_SELECTED &&
            this.selectionExists) {
          g2.setPaint(this.selectionTexture);

          //g2.fill(shp);
        }
      }
        else if (!this.selOriginalColorMode) {
          if (this.selectedObservationsFullIndex[obs] == this.STATUS_SELECTED) {
            g2.setPaint(this.selectionTexture);

            g2.fill(shp);
          }
      }
    }

    if (this.symbols != null) {
      shp.getBounds2D().getCenterX();
      shp.getBounds2D().getCenterY();
      this.renderSymbol(this.symbols[obs], shp.getBounds2D().getCenterX(),
                        shp.getBounds2D().getCenterY(), g2);
    }
  }


  private void renderSymbol(SymbolInterface sym, double x, double y,
                            Graphics2D g2d) {
    if (this.symbols != null||sym!= null) {
      sym.setX( (int) (x + 0.5));
      sym.setY( (int) (y + 0.5));
      sym.draw(g2d);
    }
  }
}